/*
 * @copyright: Huang Ding
 * @Author: ding-cx
 * @Date: 2021-08-14 17:59:05
 * @LastEditors: ding
 * @LastEditTime: 2022-10-11 09:28:03
 * @Description: file content
 */

import { actions } from "./actions";
import type { hc } from "../hc";
import BaseHttpService from "./BaseHttpService";

const logPre = "[module-baseHaiQing-person] ";

/** 海清人员名单操作  */
export default class PersonService extends BaseHttpService {
  /**
   *添加一个人员名单内容
   *
   * @param {hc.http.personInfo} person 人员信息
   * @param {string} picinfo 照片base64
   * @memberof PersonService
   */
  async addPerson(person: hc.http.personInfo, pic: { picinfo?: string; picURI?: string }) {
    if (!person.DeviceID || (person.IdType !== 0 && !person.IdType)) {
      this.app.logger.error(logPre + "新增名单，数据类型缺少必要字段DeviceID/IdType -  %s %s", this.device.ip, person.Name);
      throw new Error(`新增名单，数据类型缺少必要字段DeviceID/IdType`);
    }
    if (!pic.picinfo && !pic.picURI) {
      this.app.logger.error(logPre + "新增名单，缺少人员照片数据 入参pic：%j", pic);
      throw new Error(`新增名单，缺少人员照片`);
    }
    const data: hc.http.AddPerson = {
      operator: actions.AddPerson,
      info: person,
      picinfo: pic.picinfo || undefined,
      picURI: pic.picinfo ? undefined : pic.picURI || undefined,
    };
    return await this.request<hc.http.response>(data.operator, data);
  }

  /**
   * 修改一个人员名单
   *
   * @param {hc.http.personInfo} person
   * @param {{ picinfo?: string; picURI?: string }} pic
   * @return {*}
   * @memberof PersonService
   */
  async editPerson(person: hc.http.personInfo, pic: { picinfo?: string; picURI?: string }) {
    if (!person.DeviceID || (person.IdType !== 0 && !person.IdType)) {
      this.app.logger.error(logPre + "修改名单，数据类型缺少必要字段DeviceID/IdType -  %s %s", this.device.deviceId, person.Name);
      throw new Error(`修改名单，数据类型缺少必要字段DeviceID/IdType`);
    }
    if (!pic.picinfo && !pic.picURI) {
      this.app.logger.error(logPre + "修改名单，缺少人员照片数据 入参pic：%j", pic);
      throw new Error(`修改名单，缺少人员照片`);
    }
    const data: hc.http.editPerson = {
      operator: actions.EditPerson,
      info: person,
      picinfo: pic.picinfo || undefined,
      picURI: pic.picinfo ? undefined : pic.picURI || undefined,
    };
    return await this.request<hc.http.response>(data.operator, data);
  }

  /**
   * 下发一个人员名单，此接口仅使用小规模，会先查询设备是否有人员，有则修改，无则新增
   *
   * @param {hc.http.personInfo} person
   * @param {{ picinfo?: string; picURI?: string }} pic
   * @return {*}
   * @memberof PersonService
   */
  async sendPerson(person: hc.http.personInfo, pic: { picinfo?: string; picURI?: string }) {
    if (!person.CustomizeID) throw new Error(`can not found CustomizeID field.`)
    const cond: hc.http.searchPerson['info'] = {
      Picture: 0,
      DeviceID: this.device.deviceId,
      SearchType: person.CustomizeID ? 0 : 1,
      SearchID: person.CustomizeID || person.PersonUUID || ''
    }
    const res = await this.searchPerson(cond)
    if (res && res.info && res.info.Name) {
      return await this.editPerson(person, pic)
    }
    return await this.addPerson(person, pic)
  }


  /** 根据customizID删除名单，执行方法。私有。 */
  private async delPersonExec(idType: 0 | 2, idList: number[] | string[]) {
    const data: hc.http.deletePerson = {
      operator: actions.DeletePerson,
      info: {
        DeviceID: this.device.deviceId,
        IdType: idType,
        TotalNum: 1,
      },
    };
    if (idType === 0) {
      data.info.CustomizeID = idList as any;
    } else if (idType === 2) {
      data.info.PersonUUID = idList as any;
    }
    const res = await this.request<hc.http.response>(data.operator, data);
    return res;
  }

  /**
   *删除一个人员 by customizeID
   *
   * @param {number} customizeID 自定义id
   * @return {*}
   * @memberof PersonService
   */
  async delPerson(customizeID: number) {
    const res = await this.delPersonExec(0, [customizeID]);
    this.app.logger.info(logPre + "机器deviceID %s 删除1个名单：customizeID:  %s", this.device.deviceId, customizeID);
    return res;
  }

  /**
   * 删除多个人员 by customizeID Array
   *
   * @param {number[]} customizeIDList customizeID名单
   * @return {*}
   * @memberof PersonService
   */
  async delPersonList(customizeIDList: number[]) {
    const res = await this.delPersonExec(0, customizeIDList);
    this.app.logger.info(logPre + "机器deviceID %s 删除1个名单：customizeID:  %j", this.device.deviceId, customizeIDList);
    return res;
  }

  /**
   *删除一个人员 by personUUID
   *
   * @param {number} personUUID 自定义uuid
   * @return {*}
   * @memberof PersonService
   */
  async delPersonByPersonUUID(personUUID: string) {
    const res = await this.delPersonExec(2, [personUUID]);
    this.app.logger.info(logPre + "机器deviceID %s 删除1个名单：personUUID:  %j", this.device.deviceId, personUUID);
    return res;
  }

  /**
   * 删除多个人员 by PersonUUID Array
   *
   * @param {number[]} PersonUUIDList  名单uuid 列表
   * @return {*}
   * @memberof PersonService
   */
  async delPersonListByPersonUUID(PersonUUIDList: number[]) {
    const res = await this.delPersonExec(2, PersonUUIDList);
    this.app.logger.info(logPre + "机器deviceID %s 删除1个名单：PersonUUIDList:  %j", this.device.deviceId, PersonUUIDList);
    return res;
  }

  /** 清空一个卡机全部名单 */
  async clearAllPerson() {
    const data: hc.http.deleteAllPerson = {
      operator: actions.DeleteAllPerson,
      info: {
        DeleteAllPersonCheck: 1,
      },
    };
    const res = await this.request<hc.http.response>(data.operator, data);

    if (res && res?.code === 200) {
      this.app.logger.info(logPre + "person 删除设备上所有名单！成功！设备deviceID: %s", this.device.deviceId);
      return true;
    } else {
      this.app.logger.error(logPre + "person 删除设备上所有名单！失败！设备deviceID: %s", this.device.deviceId);
      return false;
    }
  }

  /**
   * 使用id查询单个名单信息
   *
   * @param {(string | number)} id 查询id 可能是customizID 也可能是personUUID
   * @param {boolean} [isPersonUUID=false] 是否是personUUID
   * @return {*}
   * @memberof PersonService
   */
  async searchPerson(condi: hc.http.searchPerson['info']) {
    const data: hc.http.searchPerson = {
      operator: actions.searchPerson,
      info: {
        ...condi
      },
    };
    const res = await this.request<{
      info: hc.http.personInfo;
    }>(data.operator, data);
    return res;
  }
  /**
   * 查询单个名单信息 包含照片
   *
   * @param {(string | number)} id 查询id 可能是customizID 也可能是personUUID
   * @param {boolean} [isPersonUUID=false] 是否是personUUID
   * @return {*}
   * @memberof PersonService
   */
  async getOnePersonPic(id: string | number, isPersonUUID: boolean = false) {
    const data: hc.http.searchPerson = {
      operator: actions.searchPerson,
      info: {
        DeviceID: this.device.deviceId,
        SearchType: isPersonUUID ? 1 : 0,
        SearchID: id,
        Picture: 1,
      },
    };
    const res = await this.request<{
      info: hc.http.personInfo;
      /** base64照片 */
      picinfo: string;
    }>(data.operator, data);
    return res;
  }

  /** 查询机器人员名单总数（可选条件筛选）
   * service.baseHaiQing.interface.person.searchPersonNum()
   */
  async searchPersonNum(searchCondition?: hc.http.IRequestSearchPersonNumInfo) {
    const info = searchCondition || {
      DeviceID: this.device.deviceId,
    };
    const data = {
      operator: actions.SearchPersonNum,
      info: info,
    };
    const res = await this.request<hc.http.IResponseSearchPersonNumInfo>(data.operator, data);
    return res;
  }
}
